/**
 * Copyright (c) 2008, George Taylor
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted 
 * provided that the following conditions are met:
 * 
 *   * Redistributions of source code must retain the above copyright notice, this list of 
 *     conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright notice, this list of 
 *     conditions and the following disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *   * Neither the name of the copyright holder's organization nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software without specific 
 *     prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package uk.co.taylorconsulting.annoweb.web.builder;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;

import org.apache.log4j.Logger;

import uk.co.taylorconsulting.annoweb.annotation.web.LinkParameter;
import uk.co.taylorconsulting.annoweb.web.builder.data.ActionHolder;
import uk.co.taylorconsulting.annoweb.web.builder.data.Site;

public class QuicklinkBuilder extends SiteBuilder {
	private static final Logger           LOG      = Logger.getLogger(QuicklinkBuilder.class);
	private static final QuicklinkBuilder instance = new QuicklinkBuilder();
	
	public static void buildSite(HashMap<String, Site> sites, File tmpLocation) {
		instance.buildSite(sites, tmpLocation, true);
	}
	
	public void buildSite(HashMap<String, Site> sites, File tmpLocation, boolean ok) {
		File siteFile = new File(tmpLocation, "SystemQuickLink.java");
		StringBuffer str = addClassStart(sites);
		str.append("}\n");
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(siteFile);
			fos.write(str.toString().getBytes());
			fos.close();
		} catch (Exception e) {
			LOG.warn("Error writing class to " + siteFile.getAbsolutePath() + "(" + e.getMessage() + ")");
		}
	}
	
	private StringBuffer addClassStart(HashMap<String, Site> sites) {
		Site defaultSite = sites.get("xxDefaultxx");
		StringBuffer str = new StringBuffer("import javax.servlet.http.*;\n");
		str.append("import javax.servlet.*;\n");
		str.append("import java.util.*;\n");
		str.append("import org.apache.log4j.Logger;\n");
		str.append("public class SystemQuickLink extends uk.co.taylorconsulting.web.controller.WebHelper implements uk.co.taylorconsulting.web.controller.WebFramework {\n");
		str.append("\tprivate static final Logger LOG = Logger.getLogger(SystemQuickLink.class);\n");
		str.append("\tprivate static final ").append("SystemQuickLink instance = new ").append("SystemQuickLink").append("();\n");
		str.append("\tpublic ").append("SystemQuickLink(){}\n");
		str.append("\tpublic static SystemQuickLink getInstance() {\n");
		str.append("\t\treturn instance;\n");
		str.append("\t}\n");
		str.append("\tprivate enum Actions {\n");
		str.append("\t\t");
		boolean first = true;
		for (String key : defaultSite.getGlobals().getQuickLinks().keySet()) {
			if (first) {
				first = false;
			} else {
				str.append(",");
			}
			str.append(key);
		}
		str.append(";\n");
		str.append("\t}\n");
		str.append("\tpublic void process(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {\n");
		first = true;
		str.append("\t\tString hash = request.getParameter(\"hash\");\n");
		str.append("\t\ttry {\n");
		str.append("\t\t\tString[] tokens = hash.split(\":\");\n");
		str.append("\t\t\tif (tokens.length < 2 || (!tokens[0].equalsIgnoreCase(\"ql\"))) {\n");
		str.append("\t\t\t\tLOG.warn(\"invalid quicklink recieved: \"+hash);\n");
		str.append("\t\t\t\treturn;\n");
		str.append("\t\t\t}\n");
		str.append("\t\t\tActions dispatcher = Actions.valueOf(tokens[1]);\n");
		str.append("\t\t\tswitch (dispatcher) {\n");
		for (String key : defaultSite.getGlobals().getQuickLinks().keySet()) {
			ActionHolder ah = defaultSite.getGlobals().getQuickLinks().get(key);
			str.append("\t\t\t\tcase ").append(key).append(": {\n");
			int i = 2;
			for (LinkParameter lp : ah.getQuickLinks().parameters()) {
				str.append("\t\t\t\t\trequest.setAttribute(\"").append(lp.name()).append("\",tokens[").append(i++).append("]);\n");
				str.append("\t\t\t\t\t");
				switch (lp.store()) {
					case SESSION: {
						str.append("request.getSession().setAttribute(\"");
						break;
					}
					case REQUEST: {
						str.append("request.setAttribute(\"");
					}
				}
				str.append(lp.name()).append("\",");
				MethodTypeEnum method = MethodTypeEnum.getByClass(lp.type());
				str.append(method.getMethod());
				str.append("(\"").append(lp.name()).append("\", request, false, null, null));\n");
			}
			addForward(str, null, ah.getMethod().getDeclaringClass(), ah.getMethod().getName(), false, "\t\t\t\t\t", defaultSite, null);
			str.append("\t\t\t\t}\n");
		}
		str.append("\t\t\t}\n");
		str.append("\t\t} catch (Throwable t) {LOG.warn(\"Error finding quicklink:\"+hash);}\n");
		str.append("\t}\n");
		return str;
	}
}
